<template>
  <div class="chat-container">
    <div
      style="
        width: 18%;
        border-right: #808080 2px solid;
        background-color: rgba(128, 128, 128, 0.05);
      "
    >
      <div style="padding: 20px; font-size: 20px">最近对话</div>
      <div
        v-for="chat in chats"
        :key="chat.titleId"
        style="margin-bottom: 20px"
      >
        <span
          @click="TitleByChat(chat)"
          style="color: grey; margin-left: 30px"
          >{{ chat.title }}</span
        >
      </div>
    </div>
    <div style="width: 70%; padding: 20px 120px 20px 60px">
      <!--      <h3>小博AI-Chat</h3>-->
      <div class="chat-messages">
        <div
          v-for="message in messages"
          :key="message.id"
          :class="message.isUserMessage ? 'user-message' : 'bot-message'"
        >
          <p v-html="parseMarkdown(message.content)"></p>
          <p
            v-if="message.sources && !message.isUserMessage"
            class="small-font"
          >
            <el-text
              type="primary"
              v-if="message.sources.toString().length > 0"
            >
              相关来源:
            </el-text>
            <span v-for="source in message.sources" :key="source.id">
              <br /><el-link
                type="primary"
                href="#"
                class="customer-link"
                @click.prevent="fetchPdf(source[0])"
                >{{ abbreviateContent(source[1], 68) }}</el-link
              >
            </span>
          </p>
        </div>
      </div>
      <div class="input-area">
        <el-input
          v-model="input"
          placeholder="请输入您的问题"
          size="large"
          @keyup.enter.native="sendMessage"
          class="input"
          clearable
        ></el-input>
        <el-button
          @click="sendMessage"
          :disabled="!input || input.trim() === ''"
          >文字发送</el-button
        >
        <!--:icon="Position"-->
        <el-button @click="toggleRecording">语音发送</el-button
        ><!--:icon="Mic"-->
        <el-button
          type="primary"
          @click="interrupt"
          class="btn"
          :disabled="disabled"
          >停止播报</el-button
        >
        <el-button
          type="primary"
          @click="videoHandle"
          class="btn"
          :disabled="disabled"
          >{{ curVideo ? "继续播报" : "暂停播报" }}</el-button
        >
      </div>
      <div id="jqr" style="position: absolute; bottom: 12%; right: 0"></div>
    </div>
    <!--    <div style="width: 20%;">111</div>-->
  </div>
</template>

<script>
import {
  listAiChat,
  getAiChat,
  delAiChat,
  addAiChat,
  updateAiChat,
  aiChatText,
  aiTextToAudio,
  getAiChatTitle,
  postTitleByChat,
  addTitleByChat,
  getlastTitleId,
} from "@/api/aiChat/aiChat";
import * as CryptoJS from "@/api/aiChat/crypto-js.min";
import * as cmwwPlayer from "@/api/aiChat/cmwwplayer.js";
import marked from "marked";

export default {
  name: "AiChat",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 智能问答表格数据
      aiChatList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        userId: null,
        question: null,
        answer: null,
        title: null,
      },
      // 表单参数
      // form: {},
      // 表单校验
      rules: {},
      input: "",
      messages: [
        {
          content:
            "小博AI - Chat能够回答您提出的各种问题，包括但不限于生活常识、专业知识等。并且能够扮演各种角色，如“法律顾问”、“哲学家”、“影评人”、“美食家”等，通过角色的专业性来回答您提出的问题。此外，小博AI - Chat还支持个性化定制服务，如制度筛查提取、文档提炼总结等，满足您特定场景下的需求，让您的每一次交流都更加高效和个性化。",
          isUserMessage: false,
        },
        {
          content:
            "您可以这样对我说：\n\n\t1. 请做个自我介绍\n\t2. 对员工上下班打卡审计\n\t3. 针对废旧物资的处置情况的审计\n\t4. 对公务车辆使用时间作出审计\n\t5. 对供应商不良情况作出审计",
          isUserMessage: false,
        },
      ],
      chats: [],
      mediaRecorder: null,
      chunks: [],
      audioBlob: null,
      isRecording: false,
      base_url: "http://192.168.0.113:7788",
      //数字人
      showJiaoHuBtn: false,
      inputFile: "",
      selectFileRes: null,
      env: "prd",
      url: "https://aiask365.com",
      form: {
        token: "b0779d8daf5e7129b6dbf6ac05fb229c",
        projectId: "1734120128225873920",
        question: "这是第几个问题",
        answer: `出门问问是一家以生成式AI和语音交互为核心的人工智能公司，为全球多个国家提供面向创作者的AIGC工具、AI政企服务，以及AI智能硬件。`,
      },
      disabled: true,
      curVideo: false,
      asrStatus: false,
      recognition: null,
      // isRecording: false,
      finalTranscript: "",
      transcribedText: "",
      appkey: "8EBFAFE9A067B51264046DA16E84146A",
      appSecret: "+696CD438E52E346E0778DA7713FBCC00+",
      // mediaRecorder: null,
      stream: null,
      audioChunks: [],
      expectedChunks: 0,
      pitchObject: null,
      buffer: new Float32Array(2048),
      pitchOutput: new Array(),
      pitchDropThreshold: 20,
      pitchDropDurationThreshold: 300,
      textFlag: true,
      getChatId: null,
      firstText: null,
    };
  },
  created() {
    this.getList();
    this.getToken();
    this.aiChatTitle();
    this.getTitleId();
    // this.onSubmit();
  },
  mounted() {},
  methods: {
    /** 历史记录标题查询 */
    aiChatTitle() {
      var userId = this.$store.state.user.id;
      getAiChatTitle(userId)
        .then((response) => {
          console.log("response", response);
          this.chats = response; // 假设 response.data 是你要的数据数组
        })
        .catch((error) => {
          console.error("Error:", error);
        });
    },
    getTitleId() {
      var userId = this.$store.state.user.id;
      getlastTitleId(userId)
        .then((response) => {
          console.log("response-----------------", response);
          this.getChatId = response;
        })
        .catch((error) => {
          console.error("Error:", error);
        });
    },
    /** 历史记录标题查询 */
    TitleByChat(chat) {
      const data = { userId: chat.userId, titleId: chat.titleId };
      postTitleByChat(data).then((response) => {
        console.log("response1111", response);
        const historyMessages = response.flatMap((item) => [
          { content: item.question, isUserMessage: true },
          { content: item.answer, isUserMessage: false },
        ]);
        this.messages.push(...historyMessages);
        const chatMessagesDiv = document.querySelector(".chat-messages");
        setTimeout(() => {
          chatMessagesDiv.scrollTop = chatMessagesDiv.scrollHeight;
        }, 50);
      });
    },
    addChat(data) {
      addTitleByChat(data).then((response) => {
        console.log("response1111", response);
      });
    },

    sendMessage() {
      // if (!this.input) {
      //   this.$message.error("请输入内容");
      //   return;
      // }

      const inputValue = this.input;
      if (this.textFlag) {
        this.firstText = inputValue;
        this.textFlag = false;
      }

      this.input = "";

      const userMessage = { content: inputValue, isUserMessage: true };
      this.messages.push(userMessage);

      const chatMessagesDiv = document.querySelector(".chat-messages");
      setTimeout(() => {
        chatMessagesDiv.scrollTop = chatMessagesDiv.scrollHeight;
      }, 50);
      const history = this.messages.slice(2, -1).map((msg) => ({
        role: msg.isUserMessage ? "user" : "assistant",
        content: msg.content,
      }));

      aiChatText(
        this.base_url + "/api/chat_text",
        JSON.stringify({ question: inputValue, history: history })
      )
        .then((res) => {
          console.log("res===========", res);
          // res.json()
          const botMessage = { content: res.data.answer, isUserMessage: false };
          if (res.data.sources) {
            botMessage.sources = res.data.sources;
          }
          this.messages.push(botMessage);
          this.form.question = inputValue;
          this.form.answer = res.data.answer;
          this.sendQA();
          const userId = this.$store.state.user.id;
          this.getTitleId();
          console.log("titleId----------", this.getChatId);
          const titleId = this.getChatId;
          const title = this.firstText;
          const question = this.form.question;
          const answer = this.form.answer;
          const data = {
            userId: userId,
            titleId: titleId,
            title: title,
            question: question,
            answer: answer,
          };
          this.addChat(data);
          // this.playAudio(res.data.answer);
          setTimeout(() => {
            chatMessagesDiv.scrollTop = chatMessagesDiv.scrollHeight;
          }, 50);
        })
        .catch((error) => console.log("error", error));
    },
    prepareAudio() {
      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices
          .getUserMedia({ audio: true })
          .then((stream) => {
            this.mediaRecorder = new MediaRecorder(stream);
            this.mediaRecorder.addEventListener("dataavailable", (event) => {
              this.chunks.push(event.data);
            });
            this.mediaRecorder.addEventListener("stop", () => {
              this.audioBlob = new Blob(this.chunks, { type: "audio/wav" });
              console.log("audioBlob", this.audioBlob);
              this.sendAudio();
            });
          })
          .catch((err) => console.error("无法获取麦克风权限:", err));
      } else {
        console.log("浏览器不支持 navigator.mediaDevices API");
      }
    },
    toggleRecording() {
      if (!this.isRecording) {
        console.log("开始录音");
        this.mediaRecorder.start();
        this.isRecording = true;
      } else {
        console.log("录音结束");
        this.mediaRecorder.stop();
        this.isRecording = false;
      }
    },
    playAudio(text) {
      console.log("text", text);
      aiTextToAudio(
        this.base_url + "/api/text2audio",
        JSON.stringify({ text: text })
      )
        .then((res) => {
          console.log("res22222222222===========", res);
          // res.json()
          const reader = res.body.getReader();
          const audioChunks = [];
          return new ReadableStream({
            start(controller) {
              return pump();

              function pump() {
                return reader.read().then(({ done, value }) => {
                  if (done) {
                    controller.close();
                    const audioBlob = new Blob(audioChunks, {
                      type: "audio/wav",
                    });
                    const audioURL = URL.createObjectURL(audioBlob);
                    const audio = new Audio(audioURL);
                    audio.play();
                    return;
                  }
                  audioChunks.push(value);
                  controller.enqueue(value);
                  return pump();
                });
              }
            },
          });
        })
        .catch((error) => console.log("error", error));
    },
    abbreviateContent(content, maxLength) {
      if (content.length <= maxLength) {
        return content;
      }
      return content.substring(0, maxLength) + "...";
    },
    fetchPdf(filename) {
      fetch(`${this.base_url}/api/pdf_view`, {
        method: "POST",
        headers: {
          "Content - Type": "application/json",
        },
        body: JSON.stringify({ file_name: filename }),
      })
        .then((response) => {
          if (!response.ok) {
            throw new Error("Failed to fetch PDF.");
          }
          return response.arrayBuffer();
        })
        .then((arrayBuffer) => {
          const blob = new Blob([arrayBuffer], { type: "application/pdf" });
          const objectURL = URL.createObjectURL(blob);
          const newWindow = window.open("", "_blank");
          const embed = newWindow.document.createElement("embed");
          embed.src = objectURL;
          embed.width = "100%";
          embed.height = "1000px";
          newWindow.document.body.appendChild(embed);
        })
        .catch((error) => {
          console.error(error);
        });
    },
    parseMarkdown(markdownContent) {
      return marked.parse(markdownContent);
    },
    /** 查询智能问答列表 */
    getList() {
      this.loading = true;
      listAiChat(this.queryParams).then((response) => {
        this.aiChatList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        id: null,
        userId: null,
        question: null,
        answer: null,
        title: null,
        createTime: null,
        updateTime: null,
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.id);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加智能问答";
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids;
      getAiChat(id).then((response) => {
        this.form = response.data;
        this.open = true;
        this.title = "修改智能问答";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          if (this.form.id != null) {
            updateAiChat(this.form).then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addAiChat(this.form).then((response) => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal
        .confirm('是否确认删除智能问答编号为"' + ids + '"的数据项？')
        .then(function () {
          return delAiChat(ids);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download(
        "aiChat/aiChat/export",
        {
          ...this.queryParams,
        },
        `aiChat_${new Date().getTime()}.xlsx`
      );
    },
    //数字人操作
    stringToHex(str) {
      let hex = "";
      for (let i = 0; i < str.length; i++) {
        hex += str.charCodeAt(i).toString(16);
      }
      return hex;
    },
    playSV() {
      this.sdkPlayer.playSilentvideo();
      this.showJiaoHuBtn = false;
      //语音识别
      //this.audioToText();
      //开始录音
      //this.startRecording();
      //答案
      // this.chatText();
    },
    async startRecording() {
      try {
        this.audioChunks = [];
        this.expectedChunks = 0;
        this.stream = await navigator.mediaDevices.getUserMedia({
          audio: true,
        });
        this.mediaRecorder = new MediaRecorder(this.stream);
        this.mediaRecorder.addEventListener("dataavailable", (event) => {
          this.audioChunks.push(event.data);
          this.expectedChunks++;
        });
        this.mediaRecorder.addEventListener("stop", () => {
          console.log("已停止录制");
          if (this.audioChunks.length === this.expectedChunks) {
            console.log("数据已全部收集，可以生成文件");
            const audioBlob = new Blob(this.audioChunks, { type: "audio/wav" });
            this.audioToText(audioBlob);
            //const url = URL.createObjectURL(audioBlob);
            //console.log("url",url);
            //const a = document.createElement('a');
            //a.href = url;
            //a.download = 'recorded_audio.wav';
            //a.click();
            //URL.revokeObjectURL(url);
          } else {
            console.log("数据可能未收集完整");
          }
        });
        this.mediaRecorder.start();
      } catch (error) {
        console.error("获取音频流出错:", error);
      }
    },
    stopRecording() {
      if (this.mediaRecorder) {
        console.log("触发停止！！！！！！！！！！！");
        this.mediaRecorder.stop();
        if (this.stream) {
          const tracks = this.stream.getTracks();
          tracks.forEach((track) => {
            track.stop();
          });
        }
      }
    },
    processTranscript(transcript) {
      this.finalTranscript += transcript;
      this.transcribedText = this.finalTranscript;
      console.log(this.transcribedText);
    },
    audioToText(audioBlob) {
      const that = this;
      var myHeaders = new Headers();
      myHeaders.append("User-Agent", "Apifox/1.0.0 (https://apifox.com)");
      myHeaders.append("Accept", "*/*");
      myHeaders.append("Host", "192.168.0.113:7788");
      myHeaders.append("Connection", "keep-alive");
      myHeaders.append(
        "Content-Type",
        "multipart/form-data; boundary=--------------------------015606011149942605720419"
      );

      var formdata = new FormData();
      console.log("audioBlob", audioBlob);
      formdata.append("file", audioBlob);

      var requestOptions = {
        method: "POST",
        body: formdata,
      };

      fetch("http://192.168.0.113:7788/api/audio2text", requestOptions)
        .then((response) => response.text())
        .then((result) => {
          console.log(result);
          that.form.question = result;
          that.chatText();
        })
        .catch((error) => console.log("error", error));
    },
    chatText() {
      const that = this;
      var myHeaders = new Headers();
      myHeaders.append("User-Agent", "Apifox/1.0.0 (https://apifox.com)");
      myHeaders.append("Content-Type", "application/json");

      var raw = JSON.stringify({
        question: "111",
      });

      var requestOptions = {
        method: "POST",
        headers: myHeaders,
        body: raw,
        redirect: "follow",
      };

      fetch("http://192.168.0.113:7788/api/chat_text", requestOptions)
        .then((response) => response.text())
        .then((result) => {
          console.log(JSON.parse(result));
          let res = JSON.parse(result);
          that.form.answer = res.data.answer;
          that.sendQA();
        })
        .catch((error) => console.log("error", error));
    },
    generateAuthorizationCode(appKey, secret, timestamp) {
      const dataToHash = appKey + secret + timestamp;
      const hash = this.md5(dataToHash);
      return hash;
    },
    // 使用第三方库（如 crypto-js）实现 MD5 加密
    // 如果你的项目中没有引入 crypto-js，可以通过以下方式引入：
    // <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js">
    md5(data) {
      return CryptoJS.MD5(data).toString();
    },
    getToken() {
      //获取token和projectId zrr 2024/10/9
      var that = this;

      var myHeaders = new Headers();
      myHeaders.append("Content-Type", "application/json");

      let timestamp = parseInt(new Date().getTime() / 1000);
      let authorizationCode = this.generateAuthorizationCode(
        that.appkey,
        that.appSecret,
        timestamp
      );

      var raw = JSON.stringify({
        appkey: that.appkey,
        signature: authorizationCode,
        timestamp: timestamp,
      });
      var requestOptions = {
        method: "POST",
        headers: myHeaders,
        body: raw,
        redirect: "follow",
      };
      fetch("https://aiask365.com/avatar/openApi/login", requestOptions)
        .then((response) => response.text())
        .then((result) => {
          console.log("token======", JSON.parse(result));
          that.form.token = JSON.parse(result).data;
          //let res = JSON.parse(result);
          that.getProjectId();
        })
        .catch((error) => console.log("error", error));
    },
    getProjectId() {
      //设置数字人接口
      var that = this;
      var setHeaders = new Headers();
      setHeaders.append("Content-Type", "application/json");
      console.log("that.form.token", that.form.token);
      setHeaders.append("token", that.form.token);

      console.log("that.appkey", that.appkey);
      var rawSet = JSON.stringify({
        appkey: that.appkey,
        avatarSpeakerId: "yuanrong_1_1080p",
        ttsSpeakerId: "mohongsheng_meetfast_24k",
        speed: "0.95",
      });
      console.log("that.rawSet", rawSet);
      var requestSetting = {
        method: "POST",
        headers: setHeaders,
        body: rawSet,
        redirect: "follow",
      };

      fetch("https://aiask365.com/avatar/openApi/setProject", requestSetting)
        .then((response) => response.text())
        .then((result) => {
          console.log("resultSetting======", JSON.parse(result));
          this.form.projectId = JSON.parse(result).data;
          //let res = JSON.parse(result);
          that.onSubmit();
        })
        .catch((error) => console.log("error", error));
    },
    onSubmit() {
      console.log("mmmmmmmmmmmmmmmmmmmmmmmmmmm");
      cmwwPlayer.cmwwCli(
        {
          environment: this.env,
          host: this.url,
          containerLable: "#jqr",
          token: this.form.token,
          projectId: this.form.projectId,
          quality: 1,
          zoom: 0.3,
          volum: 1,
          asr: false,
        },
        (res) => {
          //成功回调
          this.sdkPlayer = res;
          this.sdkPlayer.on("intialSucccess", (res) => {
            // console.log('浏览器UA---->',window.navigator.userAgent)

            if (res.type === "1") {
              // 开始播放
              // console.log('111111')
              this.sdkPlayer.startPlay();
            } else if (res.type === "2") {
              // 出弹框
              console.log(res);
              this.showJiaoHuBtn = true;
            }
            // alert('初始化成功')
          });
          this.sdkPlayer.on("intialError", (err) => {
            console.log(err);
            alert("初始化失败：" + err);
          });
          this.sdkPlayer.on("message", (res) => {
            console.log("res---->", res, Date.now());
            if (res.type == "videoStart") {
              this.disabled = false;
            } else if (res.type == "videoEnd") {
              this.disabled = true;
            }
          });
          this.sdkPlayer.init();
          setTimeout(() => {
            this.sdkPlayer.playSilentvideo();
          }, 1000);
          // setTimeout(() => {
          //   this.sendQA();
          // }, 4000);
        },
        (err) => {
          //失败回调
          alert("失败回调：" + err);
        }
      );
    },
    // stop() {
    //   this.sdkPlayer.stopPlay()
    // },
    sendQA() {
      console.log("0000000000000000000000000");

      this.sdkPlayer.interrupt();
      this.sdkPlayer.playQA(this.form.question, this.form.answer);
    },
    sendStreamText() {
      if (!this.form.answer) {
        return alert("请输入答案文本");
      }
      this.sdkPlayer.interrupt();
      let answerList = this.form.answer.split("");
      this.sdkPlayer.playStreamTextStart(
        answerList.shift(),
        this.form.question
      );
      answerList.forEach((element) => {
        this.sdkPlayer.playStreamText(element);
      });
      this.sdkPlayer.playStreamTextEnd();
    },
    interrupt() {
      this.sdkPlayer.interrupt();
      this.disabled = true;
      this.curVideo = false;
    },
    destroy() {
      this.sdkPlayer.stopPlay();
    },
    selectFile(e) {
      if (e) {
        this.inputFile = e.file.name;
        this.selectFileRes = e;
        // debugger
      }
    },
    sendAudio(e) {
      e = this.selectFileRes;
      if (e) {
        let that = this;
        const file = e.file;
        const reader = new FileReader();
        reader.onload = function () {
          that.sdkPlayer.interrupt();
          //   const uint = new Uint8Array(reader.result);
          const buf2 = reader.result.slice(44);
          console.log(buf2.byteLength); // 8
          // debugger
          // sdkPlayer.playAudioSign()
          let time = Math.ceil(buf2.byteLength / 1280);

          if (time == 1) {
            that.sdkPlayer.playAudio(buf2);
            return;
          }

          for (let i = 0; i < time; i++) {
            let s = i * 1280;
            let e = (i + 1) * 1280;
            if (i == time) {
              that.sdkPlayer.playAudio(buf2.slice(s));
            } else {
              that.sdkPlayer.playAudio(buf2.slice(s, e));
            }
          }

          that.sdkPlayer.playAudioEnd();
        };
        if (file) reader.readAsArrayBuffer(file);
      }
    },
    asrStart() {
      this.asrClient.asrStart();
    },
    asrStop() {
      this.asrClient.asrStop();
    },
    asrStart1() {
      this.asrClient.asrSignStart();
    },
    asrStop1() {
      this.asrClient.asrSignEnd();
    },
    playCurVideo() {
      this.sdkPlayer.playCurVideo();
    },
    stopCurVideo() {
      this.sdkPlayer.stopCurVideo();
    },
    videoHandle() {
      if (!this.curVideo) {
        this.stopCurVideo();
        this.curVideo = true;
      } else {
        this.playCurVideo();
        this.curVideo = false;
      }
    },
    asrInit() {
      const that = this;
      this.asrClient = cmwwPlayer.asrClient({
        _projectId: that.form.projectId,
        token: that.form.token,
        host: that.url,
        cb: (val) => {
          console.log(val);
          if (val.type == "asr-part") {
            that.form.answer = val.content;
          } else if (val.type == "asr") {
            that.form.answer = val.content;
          }
        },
      });
    },
    asrHandle() {
      if (!this.asrStatus) {
        this.asrStart();
        this.asrStatus = true;
      } else {
        this.asrStop();
        this.asrStatus = false;
      }
    },
    videoAnalyse() {},
  },
};
</script>
<style>
/* 样式部分保持不变 */
body {
  font-family: "Open Sans", sans - serif;
}

.chat-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  background-color: #d9f2fc;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.chat-container h3 {
  text-align: center;
  font-size: 2.5em;
  margin-bottom: 15px;
  color: #333;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
}

.chat-messages {
  flex-grow: 1;
  overflow-y: auto;
  height: 90%;
  display: flex;
  flex-direction: column;
  margin-bottom: 10px;
  padding: 25px;
  background: #ebfffa;
  border-radius: 15px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.input-area {
  position: absolute;
  bottom: 2%;
  display: flex;
  align-items: center;
  padding: 10px 0;
  margin: 1px 10px;
}

.user-message {
  font-size: 18px;
  background-color: #a8e8f3;
  color: #333;
  padding: 20px;
  margin: 10px;
  border-radius: 20px;
  max-width: 70%;
  word-wrap: break-word;
  align-self: flex-end;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease-in-out;
}

.user-message:hover {
  transform: translateY(-5px);
}

.bot-message {
  font-size: 18px;
  background-color: #fffafa;
  color: #233142;
  padding: 20px;
  margin: 10px;
  border-radius: 20px;
  max-width: 70%;
  word-wrap: break-word;
  align-self: flex-start;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease-in-out;
}

.bot-message:hover {
  transform: translateY(-5px);
}

.small-font {
  color: #555;
  font-size: 0.9em;
}

.customer-link:hover {
  color: #222222;
}

.input {
  height: 50px;
  margin-top: 8px;
  width: 600px;
  margin-right: 5px;
}

.chat-messages div {
  opacity: 0;
  animation: fadeIn 0.8s ease-in-out forwards;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(15px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
